/* 鏂囦欢锛� w25flash.h
 * 鍔熻兘鎻忚堪锛� Flash 瀛樺偍鍣╓25Q128鐨勯┍鍔ㄧ▼搴�
 * 浣滆�咃細鐜嬬淮娉�
 * 淇敼鏃ユ湡锛�2019-06-05
 * W25Q128 鑺墖鍙傛暟锛� 16M瀛楄妭锛�24浣嶅湴鍧�绾�
 * 鍒嗕负256涓狟lock锛屾瘡涓狟lock 64K瀛楄妭
 * 涓�涓狟lock鍙堝垎涓�16涓猄ector锛屽叡4096涓猄ector锛屾瘡涓猄ector 4K瀛楄妭
 * 涓�涓猄ector鍙堝垎涓�16涓狿age锛屽叡65536涓狿age锛屾瘡涓狿age 256瀛楄妭
 * 鍐欐暟鎹搷浣滅殑鍩烘湰鍗曞厓鏄疨age锛屼竴娆¤繛缁啓鍏ユ搷浣滀笉鑳借秴杩囦竴涓狿age鐨勮寖鍥淬�傚啓鐨凱age蹇呴』鏄摝闄よ繃鐨勩��
 */

#ifndef _W25FLASH_H
#define _W25FLASH_H

#include 	"stm32f4xx_hal.h"
#include	"spi.h"		//浣跨敤鍏朵腑鐨勫彉閲� hspi1锛岃〃绀篠PI1鎺ュ彛

/*  W25Q128纭欢鎺ュ彛鐩稿叧鐨勯儴鍒嗭細CS寮曡剼鍜孲PI鎺ュ彛 锛岃嫢鐢佃矾涓嶅悓锛屾洿鏀硅繖閮ㄥ垎閰嶇疆鍗冲彲   */
// Flash_CS -->PB14, 鐗囬�変俊鍙稢S鎿嶄綔鐨勫畯瀹氫箟鍑芥暟
#define CS_PORT		GPIOB
#define CS_PIN		GPIO_PIN_14
#define SPI_HANDLE	hspi1		//SPI鎺ュ彛瀵硅薄锛屼娇鐢╯pi.h涓殑鍙橀噺 hspi1

#define	__Select_Flash()		HAL_GPIO_WritePin(CS_PORT, CS_PIN, GPIO_PIN_RESET)	//CS=0
#define	__Deselect_Flash()		HAL_GPIO_WritePin(CS_PORT, CS_PIN, GPIO_PIN_SET)	//CS=1

//===========Flash瀛樺偍鑺墖W25Q128鐨勫瓨鍌ㄥ閲忓弬鏁�================
#define		FLASH_PAGE_SIZE			256		//涓�涓狿age鏄�256瀛楄妭

#define		FLASH_SECTOR_SIZE		4096	//涓�涓猄ector鏄�4096瀛楄妭

#define		FLASH_SECTOR_COUNT		4096	//鎬诲叡4096涓� Sector

//=======1. SPI 鍩烘湰鍙戦�佸拰鎺ユ敹鍑芥暟锛岄樆濉炲紡浼犺緭============
HAL_StatusTypeDef SPI_TransmitOneByte(uint8_t byteData);	//SPI鎺ュ彛鍙戦�佷竴涓瓧鑺�
HAL_StatusTypeDef SPI_TransmitBytes(uint8_t *pBuffer, uint16_t byteCount);//SPI鎺ュ彛鍙戦�佸涓瓧鑺�

uint8_t SPI_ReceiveOneByte();	//SPI鎺ュ彛鎺ユ敹涓�涓瓧鑺�
HAL_StatusTypeDef SPI_ReceiveBytes(uint8_t *pBuffer, uint16_t byteCount);//SPI鎺ュ彛鎺ユ敹澶氫釜瀛楄妭

//=========2. W25Qxx 鍩烘湰鎺у埗鎸囦护==========
// 0xEF17,琛ㄧず鑺墖鍨嬪彿涓篧25Q128, Winbond,鐢ㄨ繃
// 0xC817锛岃〃绀鸿姱鐗囧瀷鍙蜂负GD25Q128,ELM锛岀敤杩�
// 0x1C17锛岃〃绀鸿姱鐗囧瀷鍙蜂负EN25Q128,鍙版咕EON
// 0xA117锛岃〃绀鸿姱鐗囧瀷鍙蜂负FM25Q128锛屽鏃﹀井鐢靛瓙
// 0x2018锛岃〃绀鸿姱鐗囧瀷鍙蜂负N25Q128锛岀編鍏�
// 0x2017锛岃〃绀鸿姱鐗囧瀷鍙蜂负XM25QH128锛屾姹夋柊鑺紝鐢ㄨ繃

uint16_t Flash_ReadID(void); 	// Command=0x90, Manufacturer/Device ID

uint64_t Flash_ReadSerialNum(uint32_t *High32, uint32_t *Low32); //Command=0x4B, Read Unique ID, 64-bit

HAL_StatusTypeDef Flash_WriteVolatile_Enable(void); //Command=0x50: Write Volatile Enable

HAL_StatusTypeDef Flash_Write_Enable(void); //Command=0x06: Write Enable,    浣縒EL=1
HAL_StatusTypeDef Flash_Write_Disable(void);//Command=0x04, Write Disable锛�	  浣縒EL=0

uint8_t Flash_ReadSR1(void); //Command=0x05:  Read Status Register-1,	杩斿洖瀵勫瓨鍣⊿R1鐨勫��
uint8_t Flash_ReadSR2(void); //Command=0x35:  Read Status Register-2,	杩斿洖瀵勫瓨鍣⊿R2鐨勫��

void Flash_WriteSR1(uint8_t SR1); //Command=0x01:  Write Status Register,	鍙啓SR1鐨勫��,绂佹鍐欑姸鎬佸瘎瀛樺櫒

uint32_t Flash_Wait_Busy(void);  	//璇荤姸鎬佸瘎瀛樺櫒SR1锛岀瓑寰匓USY鍙樹负0,杩斿洖鍊兼槸绛夊緟鏃堕棿
void Flash_PowerDown(void);   		//Command=0xB9: Power Down
void Flash_WakeUp(void);  			//Command=0xAB: Release Power Down

//========3. 璁＄畻鍦板潃鐨勮緟鍔╁姛鑳藉嚱鏁�========
//鏍规嵁Block  缁濆缂栧彿鑾峰彇鍦板潃,鍏�256涓狟lock
uint32_t Flash_Addr_byBlock(uint8_t BlockNo);
//鏍规嵁Sector 缁濆缂栧彿鑾峰彇鍦板潃,鍏�4096涓猄ector
uint32_t Flash_Addr_bySector(uint16_t SectorNo);
//鏍规嵁Page  缁濆缂栧彿鑾峰彇鍦板潃锛屽叡65536涓狿age
uint32_t Flash_Addr_byPage(uint16_t PageNo);

//鏍规嵁Block缂栧彿锛屽拰鍐呴儴Sector缂栧彿璁＄畻鍦板潃锛屼竴涓狟lock鏈�16涓猄ector,
uint32_t Flash_Addr_byBlockSector(uint8_t BlockNo, uint8_t SubSectorNo);
//鏍规嵁Block缂栧彿锛屽唴閮⊿ector缂栧彿锛屽唴閮≒age缂栧彿璁＄畻鍦板潃
uint32_t Flash_Addr_byBlockSectorPage(uint8_t BlockNo, uint8_t SubSectorNo,
		uint8_t SubPageNo);
//灏�24浣嶅湴鍧�鍒嗚В涓�3涓瓧鑺�
void Flash_SpliteAddr(uint32_t globalAddr, uint8_t *addrHigh, uint8_t *addrMid,
		uint8_t *addrLow);

//=======4. chip銆丅lock锛孲ector鎿﹂櫎鍑芥暟============
//Command=0xC7: Chip Erase, 鎿﹂櫎鏁翠釜鍣ㄤ欢,澶х害25绉�
void Flash_EraseChip(void);

//Command=0xD8: Block Erase(64KB) 鎿﹂櫎鏁翠釜Block, globalAddr鏄叏灞�鍦板潃锛岃�楁椂澶х害150ms
void Flash_EraseBlock64K(uint32_t globalAddr);

//Command=0x20: Sector Erase(4KB) 鎵囧尯鎿﹂櫎, globalAddr鏄墖鍖虹殑鍏ㄥ眬鍦板潃锛岃�楁椂澶х害30ms
void Flash_EraseSector(uint32_t globalAddr);

//=========5. 鏁版嵁璇诲啓鍑芥暟=============
//Command=0x03,  璇诲彇涓�涓瓧鑺傦紝浠绘剰鍏ㄥ眬鍦板潃
uint8_t Flash_ReadOneByte(uint32_t globalAddr);

//Command=0x03,  杩炵画璇诲彇澶氫釜瀛楄妭锛屼换鎰忓叏灞�鍦板潃
void Flash_ReadBytes(uint32_t globalAddr, uint8_t *pBuffer, uint16_t byteCount);

void Flash_ReadBytesDMA(uint32_t globalAddr, uint8_t *pBuffer, uint16_t byteCount);
//Command=0x0B,  楂橀�熻繛缁鍙栧涓瓧鑺傦紝浠绘剰鍏ㄥ眬鍦板潃锛� 閫熷害澶х害鏄父瑙勮鍙栫殑2鍊�
void Flash_FastReadBytes(uint32_t globalAddr, uint8_t *pBuffer,
		uint16_t byteCount);

//Command=0x02: Page program 瀵逛竴涓狿age鍐欏叆鏁版嵁锛堟渶澶�256瀛楄妭锛�, globalAddr鏄垵濮嬩綅缃殑鍏ㄥ眬鍦板潃锛岃�楁椂澶х害3ms
void Flash_WriteInPage(uint32_t globalAddr, uint8_t *pBuffer,
		uint16_t byteCount);
void Flash_WriteInPageDMA(uint32_t globalAddr, uint8_t *pBuffer,
		uint16_t byteCount);
//浠庢煇涓猄ector鐨勮捣濮嬪湴鍧�寮�濮嬪啓鏁版嵁锛屾暟鎹彲鑳借法瓒婂涓狿age,鐢氳嚦璺ㄨ秺Sector锛屾�诲瓧鑺傛暟byteCount涓嶈兘瓒呰繃64K锛屼篃灏辨槸涓�涓狟lock鐨勫ぇ灏�
void Flash_WriteSector(uint32_t globalAddr, const uint8_t *pBuffer,
		uint16_t byteCount);

#endif
